package com.duolebo.uteped_sdk.msg;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.duolebo.uteped_sdk.UTEPedEventHandler;
import com.duolebo.uteped_sdk.utils.Const;
import com.yc.nadalsdk.bean.FitnessData;
import com.yc.nadalsdk.bean.MotionSummary;
import com.yc.nadalsdk.bean.Response;
import com.yc.nadalsdk.bean.SleepData;
import com.yc.nadalsdk.bean.StressData;
import com.yc.nadalsdk.bean.WorkoutData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

/**
 * @Author: LiuYang
 * @Date: 2023/12/11 20:15
 * @Description:
 */
public class HomeMessage extends BaseMessage {
    private final static String PATH = "home";

    private static final String M_getMotionSummaryData = "getMotionSummaryData";
    //同步计步、心率、血氧历史数据
    private static final String M_syncFitnessHistoryData = "syncFitnessHistoryData";
    private static final String M_syncWorkoutHistoryData = "syncWorkoutHistoryData";
    private static final String M_syncSleepHistoryData = "syncSleepHistoryData";
    private static final String M_syncStressHistoryData = "syncStressHistoryData";
    private static final String P_startTime = "startTime";
    private static final String P_endTime = "endTime";

    /**
     * BaseCallback
     *
     * @param methodChannel methodChannel
     * @param eventHandler  eventHandler
     */
    public HomeMessage(MethodChannel methodChannel, UTEPedEventHandler eventHandler) {
        super(methodChannel, eventHandler);
    }

    @Override
    public String getPath() {
        return PATH;
    }

    @Override
    public boolean methodCallConsumed(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        if (!call.hasArgument(Const.KEY_METHOD))
            return false;

        if (super.methodCallConsumed(call, result))
            return true;

        int startTime;
        int endTime;

        boolean consumed = true;
        String method = call.argument(Const.KEY_METHOD);
        Map<String, Object> map = new HashMap<>();
        assert method != null;

        switch (method) {
            //获取当天总计运动数据
            case M_getMotionSummaryData:
                if (uteBleClient.isConnected()) {
                    Response<MotionSummary> summaryData = uteBleClient.getUteBleConnection().getMotionSummaryData();
                    map = objectToMap(summaryData.getData(), false, false);
                }
                d("get Motion Summary:" + map);
                result.success(map);
                break;
            // 同步计步、心率、血氧历史数据
            case M_syncFitnessHistoryData:
                Map<String, Integer> timeParams = getTimeBetweenMap(call, result);

                if (timeParams != null && uteBleClient.isConnected()) {
                    startTime = Objects.requireNonNull(timeParams.get(P_startTime));
                    endTime = Objects.requireNonNull(timeParams.get(P_endTime));

                    Response<FitnessData> fitnessDataResponse = uteBleClient.getUteBleConnection().syncFitnessHistoryData(startTime, endTime);
                    map = objectToMap(fitnessDataResponse.getData(), false, false);
                    d("sync Fitness History Data:" + map.toString());
                }

                result.success(map);
                break;
            case M_syncWorkoutHistoryData:

                timeParams = getTimeBetweenMap(call, result);
                if (timeParams != null && uteBleClient.isConnected()) {
                    startTime = Objects.requireNonNull(timeParams.get(P_startTime));
                    endTime = Objects.requireNonNull(timeParams.get(P_endTime));

                    Response<List<WorkoutData>> workoutHistoryData = uteBleClient.getUteBleConnection().syncWorkoutHistoryData(startTime, endTime);
                    d("sync Workout History Data:" + workoutHistoryData.toString());
                    map = new HashMap<>();
                    map.put(Const.KEY_LIST, workoutHistoryData.getData());
                }

                result.success(map);
                break;
            case M_syncSleepHistoryData:
                timeParams = getTimeBetweenMap(call, result);
                if (timeParams != null && uteBleClient.isConnected()) {
                    startTime = Objects.requireNonNull(timeParams.get(P_startTime));
                    endTime = Objects.requireNonNull(timeParams.get(P_endTime));

                    Response<List<SleepData>> sleepHistoryData = uteBleClient.getUteBleConnection().syncSleepHistoryData(startTime, endTime);
                    d("sync Sleep History Data:" + sleepHistoryData.getData());
                    map.put(Const.KEY_LIST, sleepHistoryData.getData());
                }

                result.success(map);
                break;
            case M_syncStressHistoryData:
                timeParams = getTimeBetweenMap(call, result);

                if (timeParams != null && uteBleClient.isConnected()) {
                    startTime = Objects.requireNonNull(timeParams.get(P_startTime));
                    endTime = Objects.requireNonNull(timeParams.get(P_endTime));

                    Response<List<StressData>> stressHistoryData = uteBleClient.getUteBleConnection().syncStressHistoryData(startTime, endTime);
                    d("sync Stress History Data:" + stressHistoryData.getData());
                    map = new HashMap<>();
                    map.put(Const.KEY_LIST, stressHistoryData.getData());
                }

                result.success(map);
                break;
            default:
                consumed = false;
                result.success(-1);
                break;
        }

        return consumed;
    }

    @Nullable
    private Map<String, Integer> getTimeBetweenMap(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        Map<String, Integer> timeParams = call.argument(Const.TYPE_MAP);
        assert timeParams != null;
        if (!timeParams.containsKey(P_startTime) || !timeParams.containsKey(P_endTime)) {
            result.success(-1);
            return null;
        }
        d(timeParams.toString());
        return timeParams;
    }
}
